#include "infoprint.h"
#include <QVBoxLayout>
#include <QScrollBar>
#include <QDateTime>
#include <QFileDialog>
#include <QMessageBox>
#include <QProgressDialog>
#include <QApplication>
#include <QFile>
#include <QTextStream>
#include "log.h"

// 单例实例
static InfoPrint* s_instance = nullptr;

InfoPrint* InfoPrint::instance(QWidget *parent)
{
    if (s_instance == nullptr) {
        s_instance = new InfoPrint(parent);
    }
    return s_instance;
}

InfoPrint::InfoPrint(QWidget *parent)
    : QWidget(parent)
    , m_infoPrint(new QTextEdit(this))
    , m_autoScroll(true)
    , m_maxLogLines(1000)
{
    InitInfoPrint();
}

InfoPrint::~InfoPrint()
{
    s_instance = nullptr;
}

void InfoPrint::InitInfoPrint()
{
    // 设置颜色
    colorTrace = QColor(150, 150, 150);  // 灰色
    colorDebug = QColor(0, 128, 0);      // 绿色
    colorInfo = QColor(0, 0, 255);       // 蓝色
    colorWarning = QColor(255, 165, 0);  // 橙色
    colorError = QColor(255, 0, 0);      // 红色
    colorFatal = QColor(128, 0, 128);    // 紫色
    
    // 设置窗口布局
    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    
    // 配置文本编辑器
    m_infoPrint->setReadOnly(true);
    m_infoPrint->setLineWrapMode(QTextEdit::WidgetWidth);
    
    // 设置字体
    QFont font = m_infoPrint->font();
    font.setFamily("Consolas");
    font.setPointSize(10);
    m_infoPrint->setFont(font);
    
    layout->addWidget(m_infoPrint);
    setLayout(layout);
    
    // 添加初始欢迎消息
    info(tr("日志窗口初始化完成"));
}

void InfoPrint::setFixedSize(const QSize &size)
{
    QWidget::setFixedSize(size);
    m_infoPrint->setFixedSize(size);
}

void InfoPrint::setFixedSize(const int& width, const int& height)
{
    QWidget::setFixedSize(width, height);
    m_infoPrint->setFixedSize(width, height);
}

void InfoPrint::addLogMessage(const QString& message, Log_Level level)
{
    // 获取当前时间
    QString timeStr = getCurrentTime();
    
    // 根据日志级别选择颜色
    QColor textColor;
    switch (level) {
        case Log_Level::Trace: textColor = colorTrace; break;
        case Log_Level::Debug: textColor = colorDebug; break;
        case Log_Level::Info: textColor = colorInfo; break;
        case Log_Level::Warning: textColor = colorWarning; break;
        case Log_Level::Error: textColor = colorError; break;
        case Log_Level::Fatal: textColor = colorFatal; break;
        default: textColor = colorInfo; break;
    }
    
    // 创建并存储日志条目
    LogEntry entry;
    entry.message = message;
    entry.level = level;
    entry.timestamp = QDateTime::currentDateTime();
    m_logEntries.append(entry);
    
    // 限制日志条目数量
    while (m_logEntries.size() > m_maxLogLines) {
        m_logEntries.removeFirst();
    }
    
    // 构建格式化的日志消息
    QString levelStr = logLevelToString(level);
    QString formattedMessage = QString("[%1] [%2] %3").arg(timeStr, levelStr, message);
    
    // 添加到文本编辑器
    m_infoPrint->setTextColor(textColor);
    m_infoPrint->append(formattedMessage);
    
    // 自动滚动到底部
    if (m_autoScroll) {
        QScrollBar* scrollBar = m_infoPrint->verticalScrollBar();
        scrollBar->setValue(scrollBar->maximum());
    }
    
    // 发出日志添加信号
    emit logAdded(message, level);
}

void InfoPrint::trace(const QString& message)
{
    addLogMessage(message, Log_Level::Trace);
}

void InfoPrint::debug(const QString& message)
{
    addLogMessage(message, Log_Level::Debug);
}

void InfoPrint::info(const QString& message)
{
    addLogMessage(message, Log_Level::Info);
}

void InfoPrint::warning(const QString& message)
{
    addLogMessage(message, Log_Level::Warning);
}

void InfoPrint::error(const QString& message)
{
    addLogMessage(message, Log_Level::Error);
}

void InfoPrint::fatal(const QString& message)
{
    addLogMessage(message, Log_Level::Fatal);
}

void InfoPrint::clear()
{
    m_infoPrint->clear();
    m_logEntries.clear();
    info(tr("日志已清空"));
}

bool InfoPrint::saveToFile(const QString& filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        error(tr("无法打开文件进行保存: %1").arg(filePath));
        return false;
    }
    
    QTextStream out(&file);
    out << m_infoPrint->toPlainText();
    file.close();
    
    info(tr("日志已保存到: %1").arg(filePath));
    return true;
}

bool InfoPrint::exportLogs(const QString& filePath, Log_Level minLevel)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        error(tr("无法打开文件进行导出: %1").arg(filePath));
        emit logExportFinished(false, filePath);
        return false;
    }
    
    QTextStream out(&file);
    
    // 添加导出信息头
    out << "===================================\n";
    out << tr("MapTool 日志导出") << "\n";
    out << tr("导出时间: %1").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")) << "\n";
    out << tr("最低日志级别: %1").arg(logLevelToString(minLevel)) << "\n";
    out << "===================================\n\n";
    
    // 创建进度对话框
    QProgressDialog progress(tr("正在导出日志..."), tr("取消"), 0, m_logEntries.size(), QApplication::activeWindow());
    progress.setWindowModality(Qt::WindowModal);
    progress.setMinimumDuration(0);
    progress.show();
    
    // 导出符合最低级别要求的日志
    int count = 0;
    for (int i = 0; i < m_logEntries.size(); ++i) {
        const LogEntry& entry = m_logEntries.at(i);
        
        // 更新进度
        progress.setValue(i);
        QApplication::processEvents();
        if (progress.wasCanceled()) {
            file.close();
            warning(tr("日志导出已取消"));
            emit logExportFinished(false, filePath);
            return false;
        }
        
        // 检查日志级别
        if (static_cast<int>(entry.level) >= static_cast<int>(minLevel)) {
            out << formatLogMessage(entry.message, entry.level) << "\n";
            count++;
        }
    }
    
    // 添加导出信息尾
    out << "\n===================================\n";
    out << tr("共导出 %1 条日志记录").arg(count) << "\n";
    out << "===================================\n";
    
    file.close();
    
    // 完成进度
    progress.setValue(m_logEntries.size());
    
    info(tr("已导出 %1 条日志记录到: %2").arg(count).arg(filePath));
    emit logExportFinished(true, filePath);
    return true;
}

QString InfoPrint::formatLogMessage(const QString& message, Log_Level level)
{
    QString levelStr = logLevelToString(level);
    QString timeStr = m_logEntries.isEmpty() ? 
        getCurrentTime() : 
        m_logEntries.last().timestamp.toString("yyyy-MM-dd HH:mm:ss.zzz");
    
    return QString("[%1] [%2] %3").arg(timeStr, levelStr, message);
}

QString InfoPrint::logLevelToString(Log_Level level)
{
    switch (level) {
        case Log_Level::Trace: return tr("跟踪");
        case Log_Level::Debug: return tr("调试");
        case Log_Level::Info: return tr("信息");
        case Log_Level::Warning: return tr("警告");
        case Log_Level::Error: return tr("错误");
        case Log_Level::Fatal: return tr("致命");
        default: return tr("未知");
    }
}

QString InfoPrint::getCurrentTime()
{
    return QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
}

void InfoPrint::setAutoScroll(bool autoScroll)
{
    m_autoScroll = autoScroll;
    info(tr("自动滚动设置为: %1").arg(autoScroll ? tr("开启") : tr("关闭")));
}

void InfoPrint::setMaxLogLines(int maxLines)
{
    if (maxLines > 0) {
        m_maxLogLines = maxLines;
        
        // 移除多余的日志条目
        while (m_logEntries.size() > m_maxLogLines) {
            m_logEntries.removeFirst();
        }
        
        info(tr("最大日志行数设置为: %1").arg(maxLines));
    }
}

int InfoPrint::getLogCount() const
{
    return m_logEntries.size();
}

void InfoPrint::filterByLevel(Log_Level minLevel)
{
    // 清空当前显示
    m_infoPrint->clear();
    
    // 重新显示符合级别要求的日志
    for (const LogEntry& entry : m_logEntries) {
        if (static_cast<int>(entry.level) >= static_cast<int>(minLevel)) {
            // 根据日志级别选择颜色
            QColor textColor;
            switch (entry.level) {
                case Log_Level::Trace: textColor = colorTrace; break;
                case Log_Level::Debug: textColor = colorDebug; break;
                case Log_Level::Info: textColor = colorInfo; break;
                case Log_Level::Warning: textColor = colorWarning; break;
                case Log_Level::Error: textColor = colorError; break;
                case Log_Level::Fatal: textColor = colorFatal; break;
                default: textColor = colorInfo; break;
            }
            
            // 构建格式化的日志消息
            QString timeStr = entry.timestamp.toString("yyyy-MM-dd HH:mm:ss.zzz");
            QString levelStr = logLevelToString(entry.level);
            QString formattedMessage = QString("[%1] [%2] %3").arg(timeStr, levelStr, entry.message);
            
            // 添加到文本编辑器
            m_infoPrint->setTextColor(textColor);
            m_infoPrint->append(formattedMessage);
        }
    }
    
    info(tr("日志过滤级别设置为: %1").arg(logLevelToString(minLevel)));
}

// 全局函数实现
void TraceLogPrint(const QString& message)
{
    InfoPrint::instance()->trace(message);
}

void DebugLogPrint(const QString& message)
{
    InfoPrint::instance()->debug(message);
}

void InfoLogPrint(const QString& message)
{
    InfoPrint::instance()->info(message);
}

void WarningLogPrint(const QString& message)
{
    InfoPrint::instance()->warning(message);
}

void ErrorLogPrint(const QString& message)
{
    InfoPrint::instance()->error(message);
}

void FatalLogPrint(const QString& message)
{
    InfoPrint::instance()->fatal(message);
}
